using System;
using System.Configuration;

namespace NWrapper.Config
{
	/// <summary>
	/// Represents the settings for a given repository.
	/// </summary>
	public class RepositorySettings : ConfigurationElement
	{
		/// <summary>
		/// Default constructor.
		/// </summary>
		public RepositorySettings()
			: base()
		{
		}

		/// <summary>
		/// Sets the repository configuration to use the given repository name and type.
		/// </summary>
		/// <param name="name">The repository name.</param>
		/// <param name="type">The repository type.</param>
		/// <remarks>
		/// The repository name is used by <see cref="NWrapper.Attributes.EntityAttribute"/> to associate
		/// entities with their repositories.
		/// </remarks>
		public RepositorySettings(string name, RepositoryType type)
			: base()
		{
			this.Name = name;
			this.Type = type;
		}

		/// <summary>
		/// Gets or sets the repository name.
		/// </summary>
		[ConfigurationProperty("name", IsKey = true, IsRequired = true)]
		public string Name
		{
			get { return (string)(base["name"]); }
			set { base["name"] = value; }
		}

		/// <summary>
		/// Gets or sets the repository type.
		/// </summary>
		[ConfigurationProperty("type", IsRequired = true)]
		public RepositoryType Type
		{
			get { return (RepositoryType)(base["type"]); }
			set { base["type"] = value; }
		}

		/// <summary>
		/// Gets or sets the name of the assembly. Should be used when you are using
		/// the custom repository type.
		/// </summary>
		[ConfigurationProperty("assembly")]
		public string Assembly
		{
			get
			{
				object asm = base["assembly"];
				if (asm == null)
					return String.Empty;
				else
					return asm.ToString();
			}
			set { base["assembly"] = value; }
		}

		/// <summary>
		/// Gets or sets the name of the class that implements this repository. 
		/// This class must implement <see cref="IRepository"/>.
		/// Should be used when you are using the custom repository type.
		/// </summary>
		[ConfigurationProperty("class")]
		public string Class
		{
			get
			{
				object cls = base["class"];
				if (cls == null)
					return String.Empty;
				else
					return cls.ToString();
			}
			set { base["class"] = value; }
		}

		/// <summary>
		/// A collection of <see cref="EntitySettings"/> to be associated
		/// with this repository.
		/// </summary>
		[ConfigurationProperty("entities")]
		public ConfigurationElementCollection<EntitySettings> Entities
		{
			get { return (ConfigurationElementCollection<EntitySettings>)base["entities"]; }
			set { base["entities"] = value; }
		}

		/// <summary>
		/// A set of key/value pairs that are exposed to the underlying repository and
		/// permit custom configuration commands to be passed to the repository.
		/// </summary>
		[ConfigurationProperty("custom")]
		public KeyValueConfigurationCollection Custom
		{
			get { return (KeyValueConfigurationCollection)base["custom"]; }
			set { base["custom"] = value; }
		}

		/// <summary>
		/// String representation of these settings.
		/// </summary>
		/// <returns>The <see cref="Name"/> property.</returns>
		public override string ToString()
		{
			return this.Name;
		}
	}
}
